<?php
/**
 * Usage:
 *  $twitter = new Twitter("username", "password");
 *  $public_timeline_xml = $twitter->getPublicTimeline("xml");
 *
 * Methods:
 *    getPublicTimeline($format [, $since_id])                         <==
 *    getFriendsTimeline($format [, $id [, $since ]])                  <==
 *    getUserTimeline($format [, $id [, $count [, $since ]]])          <==
 *  showStatus($format, $id)
 *  updateStatus($status)
 *  destroyStatus($format, $id)
 *    getReplies($format [, $page [, $since [, $since_id]]])           <==
 *    getFriends($format [, $id ])                                     <==
 *    getFollowers($format [, $lite ])                                 <==
 *  getFeatured($format)
 *    showUser($format , $id [, $email ])                              <==
 *  getMessages($format [, $since [, $since_id [, $page ]]])
 *  getSentMessages($format [, $since [, $since_id [, $page ]]])
 *  newMessage($format, $user, $text)
 *  destroyMessage($format, $id)
 *    createFriendship($format, $id)                                   <==
 *    destroyFriendship($format, $id)                                  <==
 *  verifyCredentials([$format])
 *  endSession()
 *  getArchive($format [, $page ])
 *  getFavorites($format [, $id [, $page ]])
 *  createFavorite($format, $id)
 *  destroyFavorite($format, $id)
 *  followUser($format, $id)
 *  leaveUser($format, $id)
 *  lastStatusCode()
 *  lastAPICall()
 */

class Twitter {
	private $credentials;
	private $http_status;
	private $last_api_call;
	private $curl = true;
	
	public function __construct($username, $password) {
		$this->credentials = sprintf("%s:%s", $username, $password);
	}
	
	public function getPublicTimeline($format, $since_id = 0) {
		$api_call = sprintf("http://twitter.com/statuses/public_timeline.%s", $format);
		if($since_id>0) {
			$api_call .= sprintf("?since_id=%d", $since_id);
		}
		return $this->APICall($api_call);
	}
	
	public function getFriendsTimeline($format, $id = NULL, $since = NULL) {
		if($id!=NULL) {
			$api_call = sprintf("http://twitter.com/statuses/friends_timeline/%s.%s", $id, $format);
		} else {
			$api_call = sprintf("http://twitter.com/statuses/friends_timeline.%s", $format);
		}
		if($since!=NULL) {
			$api_call .= sprintf("?since=%s", urlencode($since));
		}
		return $this->APICall($api_call, true);
	}
	
	public function getUserTimeline($format, $id = NULL, $count = 20, $since = NULL) {
		if($id!=NULL) {
			$api_call = sprintf("http://twitter.com/statuses/user_timeline/%s.%s", $id, $format);
		} else {
			$api_call = sprintf("http://twitter.com/statuses/user_timeline.%s", $format);
		}
		if($count!=20) {
			$api_call .= sprintf("?count=%d", $count);
		}
		if($since!=NULL) {
			$api_call .= sprintf("%ssince=%s",
				(strpos($api_call, "?count=")===false)? "?" : "&", urlencode($since));
		}
		return $this->APICall($api_call, true);
	}
	
	public function showStatus($format, $id) {
		$api_call = sprintf("http://twitter.com/statuses/show/%d.%s", $id, $format);
		return $this->APICall($api_call);
	}
	
	public function updateStatus($status) {
		$status = urlencode(stripslashes(urldecode($status)));
		$api_call = sprintf("http://twitter.com/statuses/update.xml?status=%s", $status);
		return $this->APICall($api_call, true, true);
	}
	
	public function getReplies($format, $page = 1, $since_id = 0, $since = NULL) {
		$api_call = sprintf("http://twitter.com/statuses/replies.%s", $format);
		if($since!=NULL) {
			$api_call .= sprintf("?since=%s", urlencode($since));
		} elseif($since_id>0) {
			$api_call .= sprintf("?since_id=%d", $since_id);
		}
		if($page>1) {
			$api_call .= sprintf("%spage=%d", ($since!=NULL || $since_id>0)? "?" : "&", $page);
		}
		/* DEBUG */
		//echo $api_call;
		return $this->APICall($api_call, true);
	}
	
	public function destroyStatus($format, $id) {
		$api_call = sprintf("http://twitter.com/statuses/destroy/%d.%s", $id, $format);
		return $this->APICall($api_call, true);
	}
	
	public function getFriends($format, $id = NULL) {
		// take care of the id parameter
		if($id!=NULL) {
			$api_call = sprintf("http://twitter.com/statuses/friends/%s.%s", $id, $format);
		} else {
			$api_call = sprintf("http://twitter.com/statuses/friends.%s", $format);
		}
		return $this->APICall($api_call, true);
	}
	
	public function getFollowers($format, $lite = NULL) {
		$api_call = sprintf("http://twitter.com/statuses/followers.%s%s",
			$format, ($lite)? "?lite=true" : NULL);
		return $this->APICall($api_call, true);
	}
	
	public function getFeatured($format) {
		$api_call = sprintf("http://twitter.com/statuses/featured.%s", $format);
		return $this->APICall($api_call);
	}
	
	public function showUser($format, $id, $email = NULL) {
		if($email==NULL) {
			$api_call = sprintf("http://twitter.com/users/show/%s.%s", $id, $format);
		} else {
			$api_call = sprintf("http://twitter.com/users/show.xml?email=%s", $email);
		}
		return $this->APICall($api_call, true);
	}
	
	public function getMessages($format, $since = NULL, $since_id = 0, $page = 1) {
		$api_call = sprintf("http://twitter.com/direct_messages.%s", $format);
		if($since!=NULL) {
			$api_call .= sprintf("?since=%s", urlencode($since));
		}
		if($since_id>0) {
			$api_call .= sprintf("%ssince_id=%d",
				(strpos($api_call, "?since")===false)? "?" : "&", $since_id);
		}
		if($page>1) {
			$api_call .= sprintf("%spage=%d",
				(strpos($api_call, "?since")===false)? "?" : "&", $page);
		}
		return $this->APICall($api_call, true);
	}
	
	public function getSentMessages($format, $since = NULL, $since_id = 0, $page = 1) {
		$api_call = sprintf("http://twitter.com/direct_messages/sent.%s", $format);
		if($since!=NULL) {
			$api_call .= sprintf("?since=%s", urlencode($since));
		}
		if($since_id>0) {
			$api_call .= sprintf("%ssince_id=%d", 
				(strpos($api_call, "?since")===false)? "?" : "&", $since_id);
		}
		if($page>1) {
			$api_call .= sprintf("%spage=%d",
				(strpos($api_call, "?since")===false)? "?" : "&", $page);
		}
		return $this->APICall($api_call, true);
	}
	
	public function newMessage($format, $user, $text) {
		$text = urlencode(stripslashes(urldecode($text)));
		$api_call = sprintf("http://twitter.com/direct_messages/new.%s?user=%s&text=%s",
			$format, $user, $text);
		return $this->APICall($api_call, true, true);
	}
	
	public function destroyMessage($format, $id) {
		$api_call = sprintf("http://twitter.com/direct_messages/destroy/%s.%s", $id, $format);
		return $this->APICall($api_call, true);
	}
	
	public function createFriendship($format, $id) {
		$api_call = sprintf("http://twitter.com/friendships/create/%s.%s", $id, $format);
		return $this->APICall($api_call, true);
	}
	
	public function destroyFriendship($format, $id) {
		$api_call = sprintf("http://twitter.com/friendships/destroy/%s.%s", $id, $format);
		return $this->APICall($api_call, true);
	}
	
	public function verifyCredentials($format = NULL) {
		$api_call = sprintf("http://twitter.com/account/verify_credentials%s",
			($format != NULL) ? sprintf(".%s", $format) : NULL);
		return $this->APICall($api_call, true);
	}
	
	public function endSession() {
		$api_call = "http://twitter.com/account/end_session";
		return $this->APICall($api_call, true);
	}
	
	public function getArchive($format, $page = 1) {
		$api_call = sprintf("http://twitter.com/account/archive.%s", $format);
		if($page>1) {
			$api_call .= sprintf("?page=%d", $page);
		}
		return $this->APICall($api_call, true);
	}
	
	public function getFavorites($format, $id = NULL, $page = 1) {
		if($id==NULL) {
			$api_call = sprintf("http://twitter.com/favorites.%s", $format);
		} else {
			$api_call = sprintf("http://twitter.com/favorites/%s.%s", $id, $format);
		}
		if($page>1) {
			$api_call .= sprintf("?page=%d", $page);
		}
		return $this->APICall($api_call, true);
	}
	
	public function createFavorite($format, $id) {
		$api_call = sprintf("http://twitter.com/favorites/create/%d.%s", $id, $format);
		return $this->APICall($api_call, true);
	}
	
	public function destroyFavorite($format, $id) {
		$api_call = sprintf("http://twitter.com/favorites/destroy/%d.%s", $id, $format);
		return $this->APICall($api_call, true);
	}
	
	public function followUser($format, $id) {
		$api_call = sprintf("http://twitter.com/notifications/follow/%s.%s", $id, $format);
		return $this->APICall($api_call, true);
	}
	
	public function leaveUser($format, $id) {
		$api_call = sprintf("http://twitter.com/notifications/leave/%d.%s", $id, $format);
		return $this->APICall($api_call, true);
	}
	
	private function APICall($api_url, $require_credentials = false, $http_post = false) {
		if($this->curl) {
			$curl_handle = curl_init();
			curl_setopt($curl_handle, CURLOPT_URL, $api_url);
			if($require_credentials) {
				curl_setopt($curl_handle, CURLOPT_USERPWD, $this->credentials);
			}
			if($http_post) {
				curl_setopt($curl_handle, CURLOPT_POST, true);
			}
			curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
			$twitter_data = curl_exec($curl_handle);
			$this->http_status = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE);
			$this->last_api_call = $api_url;
			curl_close($curl_handle);
		} else {
			$http_response = "";
			$url = parse_url($api_url);
			$fp = fsockopen($url[host], 80);
			fputs($fp, "GET /$url[path]?$url[query] HTTP/1.0\n");
			fputs($fp, "Authorization: Basic ".base64_encode("twitwords:3r3t1c0"));
			fputs($fp, "Connection: close\n\n");
			$twitter_data = stream_get_contents($fp);
			fclose($fp);

			$twitter_data = substr($twitter_data, strrpos($twitter_data, "<?xml"));
		}
		
		/* DEBUG */
		//echo $twitter_data;
		//echo $this->http_status;
		return $twitter_data;
	}
	
	public function lastStatusCode() {
		return $this->http_status;
	}
	
	public function lastAPICall() {
		return $this->last_api_call;
	}
}
?>